import * as THREE from 'three'
import * as THREE from 'three'
// import TWEEN from "@tweenjs/tween.js";
import Orbitcontrols from 'three-orbitcontrols'
import TWEEN from '@tweenjs/tween.js'
//引入stl文件
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
class createds {
  static scene
  static camera
  static renderer
  static geometry
  static material
  static mesh
  static controls
  static directionalLight
  static dhelper
  static hemisphereLight
  static hHelper
  static container
  static refs
  static tween
  constructor(container, ref) {
    this.container = container
    this.refs = ref
  }
  init() {
    //初始化场景
    this.scene = new THREE.Scene()
    //初始化相机
    this.camera = new THREE.PerspectiveCamera(
      50,
      this.refs.value.clientWidth / this.refs.value.clientHeight,
      1,
      10000
    )
    //相机辅助对象
    let helper = new THREE.CameraHelper(this.camera)
    // this.scene.add(helper);
    //相机位置
    // this.camera.position.set(0, 15, 120);
    this.camera.position.set(0, 400, 500)
    //相机观看位置
    this.camera.lookAt({
      //相机看向哪个坐标
      x: 0,
      y: 0,
      z: 0,
    })
    //增加物体
    this.initObject()
    //创建灯光
    this.directionalLight = new THREE.DirectionalLight(0xffffff, 1)
    this.directionalLight.position.set(0, 450, 100)
    this.dhelper = new THREE.DirectionalLightHelper(
      this.directionalLight,
      55,
      0x999555
    )

    this.hemisphereLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.1)
    this.hemisphereLight.position.set(100, 700, 0)
    this.hHelper = new THREE.HemisphereLightHelper(
      this.hemisphereLight,
      55,
      0xff9999
    )

    this.scene.add(this.directionalLight)
    this.scene.add(this.hemisphereLight)
    // this.scene.add(this.dhelper);
    // this.scene.add(this.hHelper);
    //初始化渲染器
    this.renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: true,
      logarithmicDepthBuffer: true,
    })
    let cubeLoader = new THREE.CubeTextureLoader()
    //六张图片分别是朝前的（posz）、朝后的（negz）、朝上的（posy）、朝下的（negy）、朝右的（posx）和朝左的（negx）
    let bj = [
      '/image/posx.jpg',
      '/image/negx.jpg',
      '/image/posy.jpg',
      '/image/negy.jpg',
      '/image/posz.jpg',
      '/image/negz.jpg',
    ]
    this.scene.background = cubeLoader.load(bj)
    this.renderer.setPixelRatio(window.devicePixelRatio)
    this.renderer.autoClear = false
    this.renderer.shadowMap.enabled = true
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
    //渲染的背景颜色
    this.renderer.setClearColor(new THREE.Color('rgab(255,255,255)'))
    //渲染器窗口大小
    this.renderer.setSize(
      this.refs.value.clientWidth,
      this.refs.value.clientHeight
    )
    this.renderer.domElement.style.outline = 'none'
    this.refs.value.appendChild(this.renderer.domElement)
    //创建控制器
    this.controls = new Orbitcontrols(this.camera, this.renderer.domElement)
    // this.controls.target = new THREE.Vector3(0, 1, 0);
    this.controls.target.set(0, 5, 0)
    // this.controls.maxPolarAngle = (1 * Math.PI) / 2;
    //惯性
    this.controls.enableDamping = true
    //动态阻尼系数 就是鼠标拖拽旋转灵敏度
    this.controls.dampingFactor = 0.1
    //是否缩放
    this.controls.enableZoom = true
    //右键拖拽
    this.controls.enablePan = true
    //是否自动旋转
    this.controls.autoRotate = false
    //设置相机距离原点的最远距离
    this.controls.minDistance = 1
    //设置相机距离原点的最远距离
    this.controls.maxDistance = 2000
  }
  //创建对象集合
  initObject() {
    this.grid()
    this.initModel()
    // this.floor();
    // this.addText()
  }
  //创建放光⚽️
  // 加载STL模型
  initModel() {
    let loader = new STLLoader()
    let mesh
    loader.load(`/stl.STL`, (geometry) => {
      // 创建材质
      // geometry = new THREE.BoxGeometry(100, 100, 100);
      const material = new THREE.MeshLambertMaterial({ color: 0x7777ff })
      // mesh = new THREE.Mesh(geometry, material);
      // mesh.position.set(0, 0, 0);
      // mesh.rotation.x = -0.5 * Math.PI;
      // mesh.scale.set(0, 0, 0);
      mesh = new THREE.Mesh(geometry, material)
      mesh.rotation.x = 0
      mesh.rotation.y = 0
      mesh.rotation.z = 0
      mesh.position.set(-30, -5, -35)
      mesh.name = 'car'
      console.log(mesh, 'mesh')
      //设置物体大小
      mesh.scale.set(0.1, 0.1, 0.1)
      this.scene.add(mesh)
      console.log(this.scene.children, '0000')
    })
  }
  //创建网格对象
  grid() {
    let material, groundGeom, map, groundMesh
    //创建平面
    groundGeom = new THREE.PlaneGeometry(800, 800, 500)
    //加载图片
    map = new THREE.TextureLoader().load('/di.jpg')
    //创建平面贴图
    material = new THREE.MeshLambertMaterial({
      side: THREE.DoubleSide,
      map: map,
    })
    //将平面图形添加到场景当中
    groundMesh = new THREE.Mesh(groundGeom, material)
    //修改平面位置
    groundMesh.rotation.x = -Math.PI / 2
    //增加
    this.scene.add(groundMesh)
    // let textureLoader, photoFrameMaterial;
    let geometry = new THREE.PlaneBufferGeometry(800, 800)
    // //坐标系
    let axes = new THREE.AxisHelper(800)
    // textureLoader = new THREE.TextureLoader();
    // textureLoader.load('../src/assets/image/cd.jpg', (texture) => {
    //   photoFrameMaterial = new THREE.MeshPhongMaterial({
    //     // color: '#000000',
    //     side: THREE.DoubleSide,
    //     specular: '#fff',
    //     shininess: 30,
    //     transparent: true,
    //     opacity: 1,
    //   });
    //   let mesh = new THREE.Mesh(geometry, photoFrameMaterial);
    //   mesh.rotation.x = -Math.PI / 2;
    //   this.scene.add(mesh);
    // });
    // //网格
    // // this.scene.add(new THREE.GridHelper(800, 100));
    this.scene.add(axes)
  }
  /**创建文字 */
  addText() {
    let fontloader
    fontloader = new THREE.FontLoader()
    fontloader.load('../src/assets/font/KaiTi_Regular.json', (font) => {
      // let text="请在另一面创建标记点";
      let text = '请在另一面创建标记点'
      let g = new THREE.TextGeometry(text, {
        font: font,
        size: 5,
        height: 1,
      })
      g.computeBoundingBox()
      //3D文字材质
      let m = new THREE.MeshBasicMaterial({ color: 0xffff00 })
      let mesh = new THREE.Mesh(g, m)
      mesh.name = 'text'
      mesh.rotation.y = -Math.PI / 1
      mesh.position.set(34.5, 30, 0)
      // 加入到场景中
      this.scene.add(mesh)
    })
  }
  /**创建平面图 */
  floor() {
    let textureLoader, photoFrameMaterial
    //创建一个矩形
    let geometry = new THREE.PlaneGeometry(100, 50, 1)
    //创建纹理加载器对象
    textureLoader = new THREE.TextureLoader()
    // 执行load方法，加载纹理贴图成功后，返回一个纹理对象Texture
    textureLoader.load('../src/assets/image/pic.jpg', (texture) => {
      photoFrameMaterial = new THREE.MeshPhongMaterial({
        color: '#000000',
        side: THREE.DoubleSide,
        specular: '#000500',
        shininess: 30,
        transparent: true,
        opacity: 1,
      })
      //网格模型对象Mesh
      let mesh = new THREE.Mesh(geometry, photoFrameMaterial)
      mesh.position.set(0, 25, 0)
      // mesh.rotation.set(-0.5 * Math.PI, 0, 0); // 沿着 X轴旋转-90
      this.scene.add(mesh)
      //拿到回调函数返回的材质
      const material = new THREE.MeshBasicMaterial({
        map: texture,
      })
      material.transparent = true
      material.needsUpdate = true
      //将图片材质的东西放在一个空对象上面
      let cubeGeometry = new THREE.BoxGeometry(100, 50, 0)
      let cube = new THREE.Mesh(cubeGeometry, material)
      //设置图片名字
      cube.name = 'pic'
      //设置位置
      cube.position.set(0, 25, 0.1)
      //添加
      this.scene.add(cube)
    })
  }
  //增加标记
  addModel(x, y, z, r = 5, name) {
    let geometry = new THREE.CircleGeometry(r, 32)
    let material = new THREE.MeshBasicMaterial({
      color: 0xdc143c,
      side: THREE.DoubleSide,
    })
    let mesh = new THREE.Mesh(geometry, material)
    mesh.name = name
    mesh.position.set(x, y, z)
    console.log(mesh)
    this.scene.add(mesh)
  }
  //移除标记
  removeModel(delName) {
    this.scene.children.map((item, index) => {
      if (item.name == delName) {
        this.scene.children.splice(index, 1)
      }
    })
  }
  //设置标记颜色
  setColor(name, colors) {
    colors == 1 ? (colors = 'rgb(220,20,60)') : (colors = 'rgb(67, 160, 71)')
    this.scene.children.map((item, index) => {
      if (item.name == name) {
        item.material.color.set(colors)
      }
    })
  }
  //增加提示
  addTips() {
    let material = new THREE.LineBasicMaterial({ color: 0x0000ff })
    let geometry = new THREE.BufferGeometry()
    let pointsArray = new Array()
    let x = 0
    let y = 50
    let z = 0
    pointsArray.push(
      new THREE.Vector3(x, y, z),
      new THREE.Vector3(x + 0, y + 10, z + 12),
      new THREE.Vector3(x + 0, y + 30, z + 12),
      new THREE.Vector3(x + 30, y + 30, z + 12),
      new THREE.Vector3(x + 30, y + 10, z + 12),
      new THREE.Vector3(x + 0, y + 10, z + 12)
    )
    //用这个api传入顶点数组
    geometry.setFromPoints(pointsArray)

    let line = new THREE.Line(geometry, material)
    line.name = 'line'
    this.scene.add(line)
  }
  /**tween动画 */
  setAnimation(val) {
    /** */
    /** */
    // 示例化 Tween对象，并传入一个需要处理的 对象（position）
    this.tween = new TWEEN.Tween(this.camera.position)
    let origin = this.tween
    let arr = [
      { x: 500, y: 1000, z: 200 },
      { x: 500, y: 500, z: 0 },
      { x: 0, y: 550, z: 0 },
    ]
    // 在1000ms 内position.x 的值增加100
    this.tween
      .to({ x: 0, y: 55, z: 200 }, 2000)
      .easing(TWEEN.Easing.Cubic.InOut)
    this.tween.start()
    this.tween.onUpdate(function () {})
    arr.map((item) => {
      setTimeout(() => {
        let tweenSphereBack = new TWEEN.Tween(this.camera.position)
        tweenSphereBack.to(item, 2000)
        this.tween.chain(tweenSphereBack)
        // tweenSphereBack.chain(this.tween);
      }, 2000)
    })
  }
}
export default createds
